<script setup lang="ts">
  import { nextTick, ref, watch } from 'vue'
  import {
    useReceivePaymentForm,
    useGetUserUnpaidList,
  } from '@/services/pages/withdrawal/receive-payment/useReceivePayment'
  import _ from 'lodash'
  import { HMessage, HMessageBox } from '@/components/common/message'
  import { FormInstance, UploadFile, UploadRawFile } from 'element-plus'
  import { SummaryMethodProps } from '../types.s'
  import Pagination from '@/components/Pagination/index.vue'
  import { useRouter } from 'vue-router'
  import { useGetMainContactPersonOptionList } from '@/services/pages/user/useUser'
  import { fileUpload } from '@/api/upload'

  const { form, formSaveLoading, formSave, resetForm } = useReceivePaymentForm()
  const { list, listTotal, getListParam, getListLoading, getList } = useGetUserUnpaidList()
  const {
    optionList: userOptionList,
    getOptionListParam: getUserOptionListParam,
    getOptionListLoading: getUserOptionListLoading,
    getOptionList: getUserOptionList,
  } = useGetMainContactPersonOptionList()

  const emits = defineEmits<{
    (e: 'update'): void
  }>()

  // 全局路由对象
  const router = useRouter()

  // 弹窗显示状态
  const visible = defineModel('modelValue', { type: Boolean, default: false })

  // 分页组件实例
  const paginationInstance = ref<InstanceType<typeof Pagination> | null>(null)

  // 表单校验规则
  const rules = {
    userId: [{ required: true, message: '请选择客户名称', trigger: ['blur', 'change'] }],
  }

  // 表单组件实例
  const formInstance = ref<FormInstance | null>(null)

  // 收款凭证
  const voucher = ref<{ file: UploadRawFile; url: string }>({
    file: null,
    url: '',
  })

  /**
   * 客户信息清除事件
   */
  const onClearUserInfo = () => {
    form.value.userId = ''
    form.value.username = ''
    form.value.userPhone = ''
  }

  /**
   * 获取列表
   */
  const _getList = () => {
    return new Promise((resolve) => {
      nextTick(() => {
        if (paginationInstance.value && form.value.userId) {
          getListParam.value.limit = paginationInstance.value.size
          getListParam.value.page = paginationInstance.value.current
          getList(form.value.userId).then(() => {
            resolve('')
          })
        }
      })
    })
  }

  /**
   * 客户选项点击事件
   */
  const onUserNameChange = async () => {
    const user = userOptionList.value.find((itme) => itme.userId === form.value.userId)

    if (user) {
      form.value.userId = user.userId

      if (user.username) {
        form.value.username = user.username
      }

      if (user.phone) {
        form.value.userPhone = user.phone
      }

      await _getList()
    }
  }

  /**
   * 公司下拉选项搜索事件
   * @param {string} keyword - 搜搜索关键字
   */
  const handleUserSearch = _.debounce((keyword: string) => {
    if (getUserOptionListParam.value.name !== keyword) {
      getUserOptionListParam.value.name = keyword
      getUserOptionList()
    }
  }, 600)

  /**
   * 隐藏抽屉
   */
  const hideDrawer = () => {
    visible.value = false
    resetForm()
    list.value.length = 0
  }

  /**
   * 确定事件
   */
  const onConfirm = async () => {
    if (!form.value.userId) {
      HMessageBox.error('请选择公司')
      return
    }

    if (form.value.paymentOrderVos.length <= 0) {
      HMessageBox.error('请选择工单')
      return
    }

    if (!voucher.value.file) {
      HMessageBox.error('请上传支付凭证')
      return
    }

    if (formInstance.value) {
      try {
        await formInstance.value.validate()

        const imgUploadRes = await fileUpload([voucher.value.file])
        form.value.paymentOrderVos = form.value.paymentOrderVos.map((item) => {
          item.userPaymentVoucher = imgUploadRes.data.data.rows[0]
          return item
        })

        const res = await formSave()
        if (res.code === 20000) {
          hideDrawer()
          HMessage.success('保存成功')
          emits('update')
          return
        }
        HMessageBox.error(res.message)
      } catch (error) {
        // error
      }
    }
  }

  /**
   * 获取合计
   * @param param - 参数
   */
  const getSummaries = (param: SummaryMethodProps) => {
    const result: Array<string> = []
    param.columns.forEach((column, index) => {
      // 服务费合计
      if (index === 4) {
        result[4] = `￥${form.value.paymentOrderVos
          .map((item) => Number(item.serviceTotalFee))
          .reduce((prev, current) => prev + current, 0)
          .toFixed(2)}`
      }

      // 物料费合计
      if (index === 5) {
        result[5] = `￥${form.value.paymentOrderVos
          .map((item) => Number(item.spareTotalFee))
          .reduce((prev, current) => prev + current, 0)
          .toFixed(2)}`
      }

      // 总费用
      if (index === 6) {
        let totalFee = 0
        form.value.paymentOrderVos.forEach((item, index) => {
          totalFee += Number(calcRowTotalFee(index))
        })
        result[6] = `￥${totalFee.toFixed(2)}`
      }
    })
    return result
  }

  /**
   * 列表选择事件
   * @param {Array<WithdrawalUserUnpaid>} orderList - 工单列表
   */
  const handleSelectionChange = (orderList: Array<WithdrawalUserUnpaid>) => {
    form.value.paymentOrderVos = orderList.map((item) => {
      return {
        headType: item.headType,
        header: item.header,
        paymentMethod: 1,
        serviceTotalFee: item.serviceTotalFee,
        spareTotalFee: item.spareTotalfee,
        ticketType: item.ticketType,
        workId: item.workId,
        workNo: item.workNo,
        module: item.module,
        userPaymentVoucher: '',
        file: null,
      }
    })
  }

  /**
   * 工单单号点击事件
   * @param {string} orderId - 工单id
   */
  const handleOrderNoClick = (orderId: string) => {
    visible.value = false
    router.push(`/order/odetail/${orderId}`)
  }

  /**
   * 凭证上传事件
   * @param {UploadFile} file - 文件对象
   */
  const hanldeUploadVoucher = (file: UploadFile) => {
    voucher.value.file = file.raw
    voucher.value.url = URL.createObjectURL(file.raw)
  }

  /**
   * 凭证删除事件
   */
  const hanldeDelVoucher = () => {
    voucher.value.file = null
    voucher.value.url = ''
  }

  /**
   * 计算某一行的总费用
   * @param {number} index - 行索引
   */
  const calcRowTotalFee = (index: number) => {
    const receiptPayment = list.value[index]
    const materialFee = receiptPayment.spareTotalfee || 0
    const serviceFee = receiptPayment.serviceTotalFee || 0
    const total = materialFee + serviceFee
    return Number((total || 0).toFixed(0)).toFixed(2)
  }

  watch(visible, (value) => {
    if (value) {
      getUserOptionList()
    }
  })
</script>

<template>
  <h-drawer
    v-model="visible"
    title="新增收款单"
    :width="1100"
    unit="px"
    :loading="formSaveLoading || getListLoading"
    @close="hideDrawer"
  >
    <div>
      <div class="flex flex-column row-gap-5px">
        <div class="title-priamry">基本信息</div>
        <el-form ref="formInstance" :model="form" :rules="rules">
          <!-- 客户名称 -->
          <el-form-item label="客户名称：" prop="userId">
            <el-select
              v-model="form.userId"
              placeholder="请选择客户名称"
              filterable
              :loading="getUserOptionListLoading"
              :filter-method="handleUserSearch"
              clearable
              style="width: 320px"
              @change="onUserNameChange"
              @clear="onClearUserInfo"
            >
              <el-option
                v-for="userOption in userOptionList"
                :key="userOption.userId"
                :value="userOption.userId"
                :label="userOption.name"
                :disabled="userOption.disabled"
              />
            </el-select>
          </el-form-item>

          <!-- 单据备注 -->
          <el-form-item label="单据备注：" prop="remark">
            <el-input
              v-model="form.remark"
              type="textarea"
              placeholder="请输入单据备注"
              maxlength="100"
              resize="both"
              show-word-limit
            />
          </el-form-item>

          <!-- 公司电话 -->
          <el-form-item label="公司电话：">
            <template #label>
              <div>
                <span style="opacity: 0">*</span>
                公司电话：
              </div>
            </template>
            <el-input
              v-model="form.userPhone"
              placeholder="请输入公司电话"
              disabled
              style="width: 110px"
            />
          </el-form-item>

          <!-- 收款凭证 -->
          <el-form-item label="收款凭证：" prop="remark">
            <h-image
              v-if="voucher.url"
              :src="voucher.url"
              :width="80"
              :height="50"
              :padding="2"
              @del="hanldeDelVoucher"
            />
            <el-upload
              v-else
              v-model="voucher.file"
              class="order-picture-upload"
              :auto-upload="false"
              :on-change="(file: UploadFile) => hanldeUploadVoucher(file)"
              :show-file-list="false"
              accept="image/*"
              action="#"
              drag
              multiple
            >
              <el-icon :size="24" color="#007cff">
                <UploadFilled />
              </el-icon>
            </el-upload>
          </el-form-item>
        </el-form>
      </div>
      <div class="mt-36px flex flex-column row-gap-5px">
        <div class="flex column-gap-5px">
          <div class="title-priamry">工单信息</div>
        </div>
        <el-table
          ref="tableInstance"
          :border="true"
          :data="list"
          :summary-method="getSummaries"
          show-summary
          @selection-change="handleSelectionChange"
        >
          <!-- 选择 -->
          <el-table-column type="selection" width="50" :align="'center'" fixed="left" />

          <!-- 序号 -->
          <el-table-column type="index" width="50" label="序号" :align="'center'" fixed="left" />

          <!-- 工单单号 -->
          <el-table-column width="120" prop="workNo" show-overflow-tooltip label="工单单号">
            <template #default="{ row }">
              <h-link @click="handleOrderNoClick(row.workId)">{{ row.workNo }}</h-link>
            </template>
          </el-table-column>

          <!-- 工单类型 -->
          <el-table-column width="80" prop="module" show-overflow-tooltip label="工单类型" />

          <!-- 服务费 -->
          <el-table-column width="80" label="服务费">
            <template #default="{ row }">
              ￥{{ (Number(row['serviceTotalFee']) || 0).toFixed(2) }}
            </template>
          </el-table-column>

          <!-- 物料费 -->
          <el-table-column width="100" label="物料费">
            <template #default="{ row }">
              ￥{{ (Number(row['spareTotalfee']) || 0).toFixed(2) }}
            </template>
          </el-table-column>

          <!-- 总费用 -->
          <el-table-column width="100" label="总费用">
            <template #default="{ $index }"> ￥{{ calcRowTotalFee($index) }} </template>
          </el-table-column>

          <!-- 抬头类型 -->
          <el-table-column width="80" label="抬头类型">
            <template #default="{ row }">
              <template v-if="row.headType === 1">企业</template>
              <template v-if="row.headType === 2">个人</template>
            </template>
          </el-table-column>

          <!-- 发票抬头 -->
          <el-table-column min-width="120" prop="header" label="发票抬头" show-overflow-tooltip />

          <!-- 开票类型 -->
          <el-table-column width="110" label="开票类型">
            <template #default="{ row }">
              <template v-if="row.ticketType === 1">增值税普通发票</template>
              <template v-if="row.ticketType === 2">增值税专用发票</template>
            </template>
          </el-table-column>

          <!-- 发票状态 -->
          <el-table-column width="100" label="发票状态">
            <template #default="{ row }">
              <h-status v-if="row.openTicket">已申请开票</h-status>
              <h-status v-else type="warning">未申请开票</h-status>
            </template>
          </el-table-column>
        </el-table>
        <footer class="flex justify-flex-end mt-12px">
          <pagination
            ref="paginationInstance"
            :list_total="listTotal"
            @size-change="_getList"
            @current-change="_getList"
          />
        </footer>
      </div>
    </div>
    <template #footer>
      <h-button type="primary" is-modal @click="onConfirm">确定</h-button>
      <h-button is-modal @click="hideDrawer">取消</h-button>
    </template>
  </h-drawer>
</template>

<style scoped lang="scss">
  :deep(.el-form) {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    row-gap: 12px;
    column-gap: 24px;

    .el-form-item {
      .el-form-item__label {
        height: 28px;
        line-height: 28px;
      }

      .el-form-item__content {
        display: flex;
        align-items: flex-start;

        .el-select {
          width: 140px;
        }

        .el-textarea {
          .el-textarea__inner {
            width: 100% !important;
            height: 28px;
            min-height: 28px !important;
            max-height: 120px !important;
          }
        }
      }
    }
  }

  .order-picture-upload {
    width: 80px;
    height: 50px;

    :deep(.el-upload) {
      width: 100%;
      height: 100%;

      .el-upload-dragger {
        display: flex;
        align-items: center;
        column-gap: 5px;
        width: 100%;
        height: 100%;
        padding: 0;
        background: none;
        justify-content: center;
      }
    }
  }

  .user-options-wrapper {
    .user-options {
      .user-option {
        height: 35px;
        display: flex;
        column-gap: 12px;
        cursor: pointer;
        padding: 8px 10px;
        box-sizing: border-box;

        &:hover {
          background-color: #f5f7fa;
        }

        .user-name {
          width: 80px;
        }

        .is-join-black-list,
        .user-phone {
          line-height: 19px;
        }
      }
    }
  }
</style>
